﻿using System;
using System.Collections.Generic;
using System.Text;

namespace LandlordOff
{
    public class Dealing : IDealing
    {
        private Random _rand = new Random();

        /// <summary>
        /// 使用多少副牌
        /// </summary>
        public virtual const int SheetNum = 1;
        /// <summary>
        /// 每人拥有的牌数量（地主在这个基础上加上底牌的数量）
        /// </summary>
        public virtual const int CardsNumPerPlayer = 17;
        /// <summary>
        /// 玩家数量
        /// </summary>
        public virtual const int PlayerNum = 3;
        /// <summary>
        /// 牌的总数量
        /// </summary>
        public virtual const int TotalCardsNum = 54 * SheetNum;
        /// <summary>
        /// 底牌的数量
        /// </summary>
        private const int LastCardsNum = TotalCardsNum - CardsNumPerPlayer * PlayerNum;

        public Dealing()
        {
        }

        public GameStatus Distribute(IPlayer[] _players)
        {
            return Distribute(_players, 0);
        }

        /// <summary>
        /// 分牌
        /// </summary> 
        public GameStatus Distribute(IPlayer[] _players, int first)
        {
            GameStatus _status = new GameStatus();
            string _cards = Riffle();
            const int MAXSCORE = 3;
            int[] _scores = new int[_players.Length];
            int _index = 0;
            /*Distribute Cards*/
            _status.Cards = new string[_players.Length];
            for (int i = 0; i < _players.Length; i++)
            {
                string _c = _cards.Substring(_index, CardsNumPerPlayer);
                _scores[i] = _players[i].Accept(_c);
                _status.Cards[i] = _c;
                _index += CardsNumPerPlayer;
            }
            _status.LastCards = _cards.Substring(_index);
            /*Select Landlord*/
            _status.LandlordID = -1;
            int _maxScore = VaildScore(_scores[first]);
            _status.LandlordID = first;
            if (_maxScore != MAXSCORE)
                for (int i = first + 1; i < _scores.Length; i++)
                {
                    int _score = VaildScore(_scores[i]);
                    if (_score > _maxScore)
                    {
                        _maxScore = _score;
                        _status.LandlordID = i;
                        if (_maxScore == MAXSCORE)
                            break;
                    }
                }
            if (_maxScore != MAXSCORE)
                for (int i = 0; i < first; i++)
                {
                    int _score = VaildScore(_scores[i]);
                    if (_score > _maxScore)
                    {
                        _maxScore = _score;
                        _status.LandlordID = i;
                        if (_maxScore == MAXSCORE)
                            break;
                    }
                }
            /* Landlord get the last cards*/
            _status.Cards[_status.LandlordID] += _status.LastCards;
            /**/
            _status.PlayerName =new string [_players.Length ];
            for (int i = 0; i < _players.Length; i++)
                _status.PlayerName[i] = _players[i].Name;
            return _status;
        }

        /// <summary>
        /// 确保分数的有效性（1～3）
        /// </summary>
        /// <param name="_score"></param>
        /// <returns></returns>
        private int VaildScore(int _score)
        {
            return (_score > 3 || _score < 1 ? 1 : _score);
        }

        /// <summary>
        /// 洗牌
        /// </summary> 
        public string Riffle()
        {
            string _cards = Rand();
            int count = _cards.Length;
            _rand = new Random();
            int n = _rand.Next(10, 100);
            for (int i = 0; i < n; i++)
            {
                int index = _rand.Next(1, count);
                string _left = _cards.Substring(0, index);
                string _right = _cards.Substring(index);
                _cards = _right + _left;
            }
            return _cards;
        }

        private string Rand()
        {
            string _cards = string.Empty;
            for (int i = 0; i < SheetNum; i++)
                _cards += "123456789TJQK123456789TJQK123456789TJQK123456789TJQKCL";
            int count = _rand.Next(1, 10);
            for (int i = count; i > 0; i--)
            {
                _cards = Rand(_cards);
            }
            return _cards;
        }

        private string Rand(string _cards)
        {
            int count = _cards.Length;
            StringBuilder _sb = new StringBuilder(count);
            for (int i = count; i > 0; i--)
            {
                int index = _rand.Next(i);
                char c = _cards[index];
                _sb.Append(c);
                _cards = _cards.Remove(index, 1);
            }
            return _sb.ToString();
        }
    }
}
